<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <meta name="keywords" content="imlgw,半岛铁盒,blog,Java博客,程序员,个人博客,java開發,程序員,個人博客,Java">
    <meta name="description" content="大悲无泪，大悟无言，大笑无声。">
    <meta name="author" content="Resolmi">
    
    <title>
        
            JMeter压测 |
        
        Tadow
    </title>
    
<link rel="stylesheet" href="/css/style.css">

    <link rel="shortcut icon" href="https://static.imlgw.top/blog/20210731/BtJz541CcmJU.ico">
    <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/css/font-awesome.min.css">
    <script id="hexo-configurations">
    let KEEP = window.KEEP || {};
    KEEP.hexo_config = {"hostname":"imlgw.top","root":"/","language":"zh-CN","path":"search.json"};
    KEEP.theme_config = {"toc":{"enable":true,"number":true,"expand_all":true,"init_open":true},"style":{"primary_color":"#0066CC","avatar":"https://static.imlgw.top/blog/20210731/3C7hCSRR3lfq.png","favicon":"https://static.imlgw.top/blog/20210731/BtJz541CcmJU.ico","article_img_align":"left","left_side_width":"260px","content_max_width":"920px","hover":{"shadow":false,"scale":true},"first_screen":{"enable":true,"background_img":"/images/image.svg","description":"Keep It Simple & Stupid."},"scroll":{"progress_bar":{"enable":true},"percent":{"enable":true}}},"local_search":{"enable":true,"preload":false},"code_copy":{"enable":true,"style":"default"},"pjax":{"enable":true},"lazyload":{"enable":true},"version":"3.4.3"};
    KEEP.language_ago = {"second":"%s 秒前","minute":"%s 分钟前","hour":"%s 小时前","day":"%s 天前","week":"%s 周前","month":"%s 月前","year":"%s 年前"};
  </script>
<meta name="generator" content="Hexo 5.4.0"><link rel="stylesheet" href="/css/prism.css" type="text/css"></head>


<body>
<div class="progress-bar-container">
    
        <span class="scroll-progress-bar"></span>
    

    
        <span class="pjax-progress-bar"></span>
        <span class="pjax-progress-icon">
            <i class="fas fa-circle-notch fa-spin"></i>
        </span>
    
</div>


<main class="page-container">

    

    <div class="page-main-content">

        <div class="page-main-content-top">
            <header class="header-wrapper">

    <div class="header-content">
        <div class="left">
            
            <a class="logo-title" href="/">
                Tadow
            </a>
        </div>

        <div class="right">
            <div class="pc">
                <ul class="menu-list">
                    
                        <li class="menu-item">
                            <a class=""
                               href="/"
                            >
                                首页
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/archives"
                            >
                                归档
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/categories"
                            >
                                分类
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/sbe"
                            >
                                订阅
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/links"
                            >
                                友链
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/about"
                            >
                                关于
                            </a>
                        </li>
                    
                    
                        <li class="menu-item search search-popup-trigger">
                            <i class="fas fa-search"></i>
                        </li>
                    
                </ul>
            </div>
            <div class="mobile">
                
                    <div class="icon-item search search-popup-trigger"><i class="fas fa-search"></i></div>
                
                <div class="icon-item menu-bar">
                    <div class="menu-bar-middle"></div>
                </div>
            </div>
        </div>
    </div>

    <div class="header-drawer">
        <ul class="drawer-menu-list">
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/">首页</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/archives">归档</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/categories">分类</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/sbe">订阅</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/links">友链</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/about">关于</a>
                </li>
            
        </ul>
    </div>

    <div class="window-mask"></div>

</header>


        </div>

        <div class="page-main-content-middle">

            <div class="main-content">

                
                    <div class="fade-in-down-animation">
    <div class="article-content-container">

        <div class="article-title">
            <span class="title-hover-animation">JMeter压测</span>
        </div>

        
            <div class="article-header">
                <div class="avatar">
                    <img src="https://static.imlgw.top/blog/20210731/3C7hCSRR3lfq.png">
                </div>
                <div class="info">
                    <div class="author">
                        <span class="name">Resolmi</span>
                        
                            <span class="author-label">BOSS</span>
                        
                    </div>
                    <div class="meta-info">
                        <div class="article-meta-info">
    <span class="article-date article-meta-item">
        <i class="fas fa-edit"></i>&nbsp;2019-06-06 00:00:00
    </span>
    
        <span class="article-categories article-meta-item">
            <i class="fas fa-folder"></i>&nbsp;
            <ul>
                
                    <li>
                        <a href="/categories/Web/">Web</a>&nbsp;
                    </li>
                
            </ul>
        </span>
    
    
        <span class="article-tags article-meta-item">
            <i class="fas fa-tags"></i>&nbsp;
            <ul>
                
                    <li>
                        <a href="/tags/JMeter/">JMeter</a>&nbsp;
                    </li>
                
                    <li>
                        | <a href="/tags/%E7%A7%92%E6%9D%80/">秒杀</a>&nbsp;
                    </li>
                
            </ul>
        </span>
    

    
    
        <span class="article-wordcount article-meta-item">
            <i class="fas fa-file-word"></i>&nbsp;<span>2.5k 字</span>
        </span>
    
    
        <span class="article-min2read article-meta-item">
            <i class="fas fa-clock"></i>&nbsp;<span>10 分钟</span>
        </span>
    
    
        <span class="article-pv article-meta-item">
            <i class="fas fa-eye"></i>&nbsp;<span id="busuanzi_value_page_pv"></span>
        </span>
    
</div>

                    </div>
                </div>
            </div>
        

        <div class="article-content markdown-body">
            <h2 id="JMeter入门"><a href="#JMeter入门" class="headerlink" title="JMeter入门"></a>JMeter入门</h2><p><a class="link"   target="_blank" rel="noopener" href="http://jmeter.apache.org/" >官网地址<i class="fas fa-external-link-alt"></i></a> 下载好之后直接运行jar包 </p>
<h3 id="简单上手"><a href="#简单上手" class="headerlink" title="简单上手"></a>简单上手</h3><p><strong>添加线程组</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/image/20190529/wBWwVD5chqtc.png?imageslim"
                      alt="mark"
                ></p>
<p><strong>设置线程个数和配置</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/image/20190529/KonWE6pHVdMz.png?imageslim"
                      alt="mark"
                ></p>
<p>Ramp-Up就是多长时间内启动这些线程设置位0就是同时启动。</p>
<p><strong>设置HTTP请求默认值</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/image/20190529/73A4su1jMAWM.png?imageslim"
                      alt="mark"
                ></p>
<p>设置好后再添加具体的请求的时候就不用再写这个了</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/image/20190529/Uwy5zrWzFsji.png?imageslim"
                      alt="mark"
                ></p>
<p><strong>添加HTTP请求</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/image/20190529/iVbmgkdG7D88.png?imageslim"
                      alt="mark"
                ></p>
<p>这里对我们的秒杀商品列表进行压测。</p>
<p><strong>添加监听器</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/image/20190529/yVm6imNhWYKe.png?imageslim"
                      alt="mark"
                ></p>
<p>这里添加比较常用的聚合报告就可以了</p>
<p><strong>结果</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/image/20190531/C3pwAwyh7BhG.png?imageslim"
                      alt="mark"
                ></p>
<p>这里我们可以需要关注的就是吞吐量这个参数，一开始可能会不太准多测几次。</p>
<p>同时我们也可以用Linux的<code>top</code>命令查看当前CPU的利用率。</p>
<h3 id="添加自定义参数"><a href="#添加自定义参数" class="headerlink" title="添加自定义参数"></a>添加自定义参数</h3><p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/image/20190601/VQ9adD8KBfvA.png?imageslim"
                      alt="mark"
                ></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/image/20190601/j1XB0mewqvJG.png?imageslim"
                      alt="mark"
                ></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="number">17362363659</span>,3d3ae96d381d4376b87cb7ebf14aadb6</span><br><span class="line"><span class="number">12012341234</span>,fbb11e35f16b4a54be1315a0a1619193</span><br><span class="line"><span class="number">11012341234</span>,58d63f1d9482472f907829da2ae3b4ff</span><br><span class="line"><span class="number">10012341234</span>,09fe09587b924c49b6db64f763c1ad10</span><br></pre></td></tr></table></figure>

<p><strong>效果</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/image/20190601/5up85aDbSTWM.png?imageslim"
                      alt="mark"
                ></p>
<h3 id="生成token"><a href="#生成token" class="headerlink" title="生成token"></a>生成token</h3><p>方便后面的压测，可以直接写一个工具类生成token供后面的redis使用</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@RunWith(SpringJUnit4ClassRunner.class)</span></span><br><span class="line"><span class="meta">@SpringBootTest</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">TokenUtils</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> SpikeUserService spikeUserService;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">static</span> String str=<span class="string">&quot;0123456789&quot;</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">static</span>  Random random = <span class="keyword">new</span> Random();</span><br><span class="line"></span><br><span class="line">    <span class="keyword">static</span> HttpServletResponse resp;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span>  <span class="keyword">void</span> <span class="title">test</span><span class="params">()</span> <span class="keyword">throws</span> IOException </span>&#123;</span><br><span class="line">        FileOutputStream outputStream=<span class="keyword">new</span> FileOutputStream(<span class="keyword">new</span> File(<span class="string">&quot;D:\\AliyunKey\\config.txt&quot;</span>));</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;<span class="number">20000</span>;i++)&#123;</span><br><span class="line">            String phone = creatPhone();</span><br><span class="line">            RegisterVo registerVo = <span class="keyword">new</span> RegisterVo(phone,<span class="string">&quot;123456&quot;</span>,<span class="string">&quot;user-&quot;</span>+i);</span><br><span class="line">            spikeUserService.register(registerVo);</span><br><span class="line">            <span class="comment">//需要在service层token返回出来</span></span><br><span class="line">            String token= spikeUserService.login(resp, <span class="keyword">new</span> LoginVo(registerVo.getMobile(), registerVo.getPassword()));</span><br><span class="line">            outputStream.write((phone+<span class="string">&quot;,&quot;</span>+token+<span class="string">&quot;\n&quot;</span>).getBytes());</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span>  String <span class="title">creatPhone</span><span class="params">()</span></span>&#123;</span><br><span class="line">        String res=<span class="string">&quot;1&quot;</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;<span class="number">10</span>;i++)&#123;</span><br><span class="line">            res+=str.charAt(random.nextInt(<span class="number">10</span>));</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="Redis压测"><a href="#Redis压测" class="headerlink" title="Redis压测"></a>Redis压测</h3><p>①redis-benchmark -h 127.0.0.1 -p 6379 -c 100 -n 100000</p>
<p>100个并发，十万个请求，对常用的一些命令进行测试</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/image/20190601/oPkioXCFgL8R.png?imageslim"
                      alt="mark"
                ></p>
<p>②redis-benchmark -h 127.0.0.1 -p 6379 -q -d 100</p>
<p>100 bytes payload </p>
<p>-q 是quiet输出信息较少</p>
<p>③ redis-benchmark -n 100000 -q script load “redis.call(‘set’,’foo’,’bar’)”</p>
<p>对特定的语句压测</p>
<h2 id="搭建压测环境"><a href="#搭建压测环境" class="headerlink" title="搭建压测环境"></a>搭建压测环境</h2><h3 id="命令行压测"><a href="#命令行压测" class="headerlink" title="命令行压测"></a>命令行压测</h3><p>其实还是需要借助图形界面来录好jmx文件然后上传到Linux上，然后执行</p>
<p>sh jmeter.sh -n -t Xxx.jmx -l result.jtl</p>
<p>然后再用图形界面导入result.jtl就可以看到结果</p>
<blockquote>
<p>上面的测试都是在我的开发机(win)上进行的，压测和服务都在本地，结果可能并不准确，这里为了隔离环境我开了了2个虚拟机，一个是部署服务的机器（2G 4核），一个是部署mysql和redis的机器（2G 4核），这里在Linux上运行部署项目有两种方式，一种是打成war包放在tomcat目录下，一种是打成jar包直接运行。</p>
</blockquote>
<h3 id="环境"><a href="#环境" class="headerlink" title="环境"></a>环境</h3><p>✔ 192.168.25.123   Centos6  mysql+redis  2G4核</p>
<p>✔ 192.168.25.4     Centos7   SpikeServer+压测  2.5G 4核</p>
<p>✔<del>win10开发机     Jmeter压测 SpikeServer</del> </p>
<p>✔<del>192.168.25.129 Centos7 压测设备 2G4核</del></p>
<h3 id="SpringBoot打war包"><a href="#SpringBoot打war包" class="headerlink" title="SpringBoot打war包"></a>SpringBoot打war包</h3><p><strong>添加tomcat依赖(编译时依赖)</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">&lt;dependency&gt;</span><br><span class="line">    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;</span><br><span class="line">    &lt;artifactId&gt;spring-boot-starter-tomcat&lt;/artifactId&gt;</span><br><span class="line">	&lt;scope&gt;provided&lt;/scope&gt;</span><br><span class="line">&lt;/dependency&gt;</span><br></pre></td></tr></table></figure>

<p><strong>添加一个maven插件</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">&lt;plugin&gt;</span><br><span class="line">    &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;</span><br><span class="line">    &lt;artifactId&gt;maven-war-plugin&lt;/artifactId&gt;</span><br><span class="line">	&lt;configuration&gt;</span><br><span class="line">    	&lt;failOnMissingWebXml&gt;<span class="keyword">false</span>&lt;/failOnMissingWebXml&gt;</span><br><span class="line">	&lt;/configuration&gt;</span><br><span class="line">&lt;/plugin&gt;</span><br></pre></td></tr></table></figure>

<p><strong>修改pom打包方式位war</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">&lt;packaging&gt;war&lt;/packaging&gt;</span><br></pre></td></tr></table></figure>

<p><strong>boot类添加一个方法</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@SpringBootApplication</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SpikeApplication</span> <span class="keyword">extends</span> <span class="title">SpringBootServletInitializer</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        SpringApplication.run(SpikeApplication.class, args);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> builder</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span> 打 war包</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> SpringApplicationBuilder <span class="title">configure</span><span class="params">(SpringApplicationBuilder builder)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> builder.sources(SpikeApplication.class);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>然后在项目目录下执行<code>mvn clean package</code>就会在target目录下生成war包，然后将war包拷到tomcat里面就可以直接运行了。</p>
<h3 id="SpringBoot打jar包"><a href="#SpringBoot打jar包" class="headerlink" title="SpringBoot打jar包"></a>SpringBoot打jar包</h3><p><strong>pom里的打包方式改为jar(默认就是jar)</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">&lt;packaging&gt;war&lt;/packaging&gt;</span><br></pre></td></tr></table></figure>

<p><strong>添加一个maven插件</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">&lt;!--打jar包的插件--&gt;</span><br><span class="line">&lt;plugin&gt;</span><br><span class="line">    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;</span><br><span class="line">	&lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;</span><br><span class="line">&lt;/plugin&gt;</span><br></pre></td></tr></table></figure>

<p><strong>执行mvn clean package</strong></p>
<p>同上会在target目录下生成一个jar包，jar包内容大致如下</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">Manifest-Version: <span class="number">1.0</span></span><br><span class="line">Implementation-Title: Spike</span><br><span class="line">Implementation-Version: <span class="number">1.0</span>-SNAPSHOT</span><br><span class="line">Built-By: priva</span><br><span class="line">Implementation-Vendor-Id: top.imlgw</span><br><span class="line">Spring-Boot-Version: <span class="number">2.1</span><span class="number">.2</span>.RELEASE</span><br><span class="line">Main-Class: org.springframework.boot.loader.JarLauncher</span><br><span class="line">Start-Class: top.imlgw.spike.SpikeApplication</span><br><span class="line">Spring-Boot-Classes: BOOT-INF/classes/</span><br><span class="line">Spring-Boot-Lib: BOOT-INF/lib/</span><br><span class="line">Created-By: Apache Maven <span class="number">3.5</span><span class="number">.3</span></span><br><span class="line">Build-Jdk: <span class="number">1.8</span><span class="number">.0_172</span></span><br><span class="line">Implementation-URL: https:<span class="comment">//projects.spring.io/spring-boot/#/spring-bo</span></span><br><span class="line"> ot-starter-parent/Spike</span><br></pre></td></tr></table></figure>

<p>如果确少一些信息比如Main-Class和Start-Class，说明jar包打的有问题，运行会报<code>没有主清单属性</code>，我一开始没注意，我的<code>plugins</code>上层还有个<code>pluginmanagement</code>插件根本没加载进来，去掉就行了。</p>
<h2 id="开始压测"><a href="#开始压测" class="headerlink" title="开始压测"></a>开始压测</h2><h3 id="压测商品列表页面"><a href="#压测商品列表页面" class="headerlink" title="压测商品列表页面"></a>压测商品列表页面</h3><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@RequestMapping(&quot;/to_list&quot;)</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">tolist</span><span class="params">(Model model,SpikeUser spikeUser)</span> </span>&#123;</span><br><span class="line">    List&lt;GoodsVo&gt; goodsVos = goodsService.goodsVoList();</span><br><span class="line">    model.addAttribute(<span class="string">&quot;user&quot;</span>, spikeUser);</span><br><span class="line">    model.addAttribute(<span class="string">&quot;goodsList&quot;</span>,goodsVos);</span><br><span class="line">	<span class="keyword">return</span> <span class="string">&quot;goods_list&quot;</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这个接口主要就做了一个查询的mysql的操作，没有cookie所以不会去操作redis</p>
<h3 id="遇到的问题"><a href="#遇到的问题" class="headerlink" title="遇到的问题"></a>遇到的问题</h3><p>一开始直接设置了 5000*10 的并发，然后服务端报了   打开文件过多的错误</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">java.io.IOException: 打开的文件过多</span><br><span class="line">        at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method) ~[na:<span class="number">1.8</span><span class="number">.0_171</span>]</span><br><span class="line">        at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:<span class="number">422</span>) ~[na:<span class="number">1.8</span><span class="number">.0_171</span>]</span><br><span class="line">        at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:<span class="number">250</span>) ~[na:<span class="number">1.8</span><span class="number">.0_171</span>]</span><br><span class="line">        at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:<span class="number">448</span>) ~[tomcat-embed-core-<span class="number">9.0</span><span class="number">.14</span>.jar!/:<span class="number">9.0</span><span class="number">.14</span>]</span><br><span class="line">        at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:<span class="number">70</span>) ~[tomcat-embed-core-<span class="number">9.0</span><span class="number">.14</span>.jar!/:<span class="number">9.0</span><span class="number">.14</span>]</span><br><span class="line">        at org.apache.tomcat.util.net.Acceptor.run(Acceptor.java:<span class="number">95</span>) ~[tomcat-embed-core-<span class="number">9.0</span><span class="number">.14</span>.jar!/:<span class="number">9.0</span><span class="number">.14</span>]</span><br><span class="line">        at java.lang.Thread.run(Thread.java:<span class="number">748</span>) [na:<span class="number">1.8</span><span class="number">.0_171</span>]</span><br></pre></td></tr></table></figure>

<p>google后发现是句柄太少的原因，Linux默认是1024，而我们同时起了5000个线程自然就出问题了。</p>
<p>通过<code>ulimit -a</code> 可以查看到当前的最大句柄数<code>open files</code> ，这里我们可以通过 <code>ulimit -n 2048</code>临时的设置一个较大的值，但是重启后就会失效。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function">core file <span class="title">size</span>          <span class="params">(blocks, -c)</span> 0</span></span><br><span class="line"><span class="function">data seg <span class="title">size</span>           <span class="params">(kbytes, -d)</span> unlimited</span></span><br><span class="line"><span class="function">scheduling <span class="title">priority</span>             <span class="params">(-e)</span> 0</span></span><br><span class="line"><span class="function">file <span class="title">size</span>               <span class="params">(blocks, -f)</span> unlimited</span></span><br><span class="line"><span class="function">pending <span class="title">signals</span>                 <span class="params">(-i)</span> 14707</span></span><br><span class="line"><span class="function">max locked <span class="title">memory</span>       <span class="params">(kbytes, -l)</span> 64</span></span><br><span class="line"><span class="function">max memory <span class="title">size</span>         <span class="params">(kbytes, -m)</span> unlimited</span></span><br><span class="line"><span class="function">open <span class="title">files</span>                      <span class="params">(-n)</span> 1024</span></span><br><span class="line"><span class="function">pipe <span class="title">size</span>            <span class="params">(<span class="number">512</span> bytes, -p)</span> 8</span></span><br><span class="line"><span class="function">POSIX message <span class="title">queues</span>     <span class="params">(bytes, -q)</span> 819200</span></span><br><span class="line"><span class="function">real-time <span class="title">priority</span>              <span class="params">(-r)</span> 0</span></span><br><span class="line"><span class="function">stack <span class="title">size</span>              <span class="params">(kbytes, -s)</span> 8192</span></span><br><span class="line"><span class="function">cpu <span class="title">time</span>               <span class="params">(seconds, -t)</span> unlimited</span></span><br><span class="line"><span class="function">max user <span class="title">processes</span>              <span class="params">(-u)</span> 14707</span></span><br><span class="line"><span class="function">virtual <span class="title">memory</span>          <span class="params">(kbytes, -v)</span> unlimited</span></span><br><span class="line"><span class="function">file <span class="title">locks</span>                      <span class="params">(-x)</span> unlimited</span></span><br></pre></td></tr></table></figure>

<p>这里最好是直接修改  /etc/security/limits.conf</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">*  soft nofile  <span class="number">32768</span></span><br><span class="line">*  hard nofile <span class="number">65536</span></span><br></pre></td></tr></table></figure>

<p>就可以将文件句柄限制统一改成软32768，硬65536。配置文件最前面的是指domain，设置为星号代表全局，另外你也可以针对不同的用户做出不同的限制。</p>
<p>注意：这个当中的硬限制是实际的限制，而软限制，是warnning限制，只会做出warning，其实ulimit命令本身就有分软硬设置，加-H就是硬，加-S就是软</p>
<p>修改后记得重启才会生效 <a class="link"   target="_blank" rel="noopener" href="https://www.cnblogs.com/ibook360/archive/2012/05/11/2495405.html" >参考资料<i class="fas fa-external-link-alt"></i></a> </p>
<p>一开始是打算直接用win开发机做压测的，但是发现在进程开大了之后老是跑不完，跑一半就停了（可能是内存给小了），而且数据出入也比较大，然后改用秒杀服务的那条机器来压测，一开始只增大了跑秒杀服务的虚拟机，发现还是会有异常，然后我把mysql和redis的虚拟机也调大了就没报异常了，但是在压测的时候秒杀服务的虚拟机cpu飙到了 <code>9.0+</code>，4核的机子，cpu飙到这么高就有点问题了一般来说应该维持在 <code>4*0.7</code> 左右。</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/image/20190604/LedMcRvfSXeb.png?imageslim"
                      alt="mark"
                ></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/image/20190604/UbcTCaTGiEJ9.png?imageslim"
                      alt="mark"
                ></p>
<p>可以看到平均等待时间都在2s以上。</p>
<p>为了更准确的模拟，我又开了一台<del>1G2核</del> 2G4核的虚拟机专门来做压测（8G内存吃不消了）。</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/image/20190604/pr4yMAE2Jamf.png?imageslim"
                      alt="mark"
                ></p>
<p>这里用top观察了两台虚拟机的情况发现mysql的那台机器负载一直很低，SpikeServer那台机器（1G双核）负载一路飙到6.0+。吞吐率也明显的下降了，这里我连续测试了两次都是400多。</p>
<h3 id="最终配置"><a href="#最终配置" class="headerlink" title="最终配置"></a>最终配置</h3><p>经过一上午的折腾，我决定还是值利用两台你虚拟机，一台跑SpikeServer和压测，另外一台跑mysql和redis，再启动一台成本太大了，这里主要根据这个做一个标准量，后期优化后拿来对比</p>
<h4 id="结果"><a href="#结果" class="headerlink" title="结果"></a>结果</h4><p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/image/20190604/IEGxtWU8pujI.png?imageslim"
                      alt="mark"
                ></p>
<p>后面在调整机器或连续测试了5，6次 在5000的并发下QPS大概是1000左右的样子，小于1000。</p>
<h3 id="压测Redis查询的性能"><a href="#压测Redis查询的性能" class="headerlink" title="压测Redis查询的性能"></a>压测Redis查询的性能</h3><p>上面的goods_list实际上只对mysql进行了一个查询操作，而mysql的并发量并不大。</p>
<p>下面我们单独对redis做一下压测，看下系统的QPS（这里）</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/image/20190604/h2NOJszwC7Lo.png?imageslim"
                      alt="mark"
                ></p>
<h4 id="结果-1"><a href="#结果-1" class="headerlink" title="结果"></a>结果</h4><p>一开测试忘了调大redis链接池的大小，一直跑不出来，后来改大之后测了4，5次，同样的5000并发10次，QPS大概在3000左右</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/image/20190606/58L5ieKaxR7a.png?imageslim"
                      alt="mark"
                ></p>
<p>可以说是相当快了，而且<code>top</code>观察redis那台机器发现负载依然很低，说明这点并发确实对redis来说是小意思，前面其实也单独对redis用它自带的压测工具测试过，大概每秒10 0000的GET是没问题的</p>
<h3 id="重头戏—压测do-spike接口"><a href="#重头戏—压测do-spike接口" class="headerlink" title="重头戏—压测do_spike接口"></a>重头戏—压测do_spike接口</h3><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@RequestMapping(&quot;/do_spike&quot;)</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">do_spike</span><span class="params">(Model model, SpikeUser spikeUser, <span class="meta">@RequestParam(&quot;goodsId&quot;)</span> <span class="keyword">long</span> goodsId)</span> </span>&#123;</span><br><span class="line">       <span class="keyword">if</span> (spikeUser==<span class="keyword">null</span>) &#123; <span class="comment">//没有登录</span></span><br><span class="line">           <span class="keyword">return</span> <span class="string">&quot;login&quot;</span>;</span><br><span class="line">       &#125;</span><br><span class="line">       <span class="comment">//检查库存</span></span><br><span class="line">       GoodsVo goodsVo= goodsService.getGoodsVoByGoodsId(goodsId);</span><br><span class="line">       <span class="keyword">int</span> stock=goodsVo.getStockCount(); <span class="comment">//这里拿的秒杀商品里面的库存,不是商品里面的库存</span></span><br><span class="line">       <span class="keyword">if</span>(stock&lt;=<span class="number">0</span>)&#123;</span><br><span class="line">           model.addAttribute(<span class="string">&quot;failMsg&quot;</span>,CodeMsg.STOCK_EMPTY);</span><br><span class="line">           <span class="keyword">return</span> <span class="string">&quot;spike_fail&quot;</span>;</span><br><span class="line">       &#125;</span><br><span class="line">       <span class="comment">//看是否重复秒杀</span></span><br><span class="line">       SpikeOrder spikeOrder=spikeService.getGoodsVoByUserIdAndGoodsId(spikeUser.getId(), goodsId);</span><br><span class="line">       <span class="keyword">if</span>(spikeOrder!=<span class="keyword">null</span>)&#123;</span><br><span class="line">           model.addAttribute(<span class="string">&quot;failMsg&quot;</span>,CodeMsg.SKIPE_REPEAT);</span><br><span class="line">           <span class="keyword">return</span> <span class="string">&quot;spike_fail&quot;</span>;</span><br><span class="line">       &#125;</span><br><span class="line">       OrderInfo orderInfo=spikeService.doSpike(spikeUser.getId(),goodsVo);</span><br><span class="line">       model.addAttribute(<span class="string">&quot;orderInfo&quot;</span>,orderInfo);</span><br><span class="line">       model.addAttribute(<span class="string">&quot;goods&quot;</span>,goodsVo);</span><br><span class="line">       <span class="keyword">return</span> <span class="string">&quot;order_detail&quot;</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>步骤都跟上面一样，不过要多加一个商品id的参数，这里依然是5000的并发10次，其实这里测出来的结果和上面的商品列表差不太多，差不多950左右QPS，毕竟这里有判断库存的操作，一旦小于0之后就不会对mysql再进行操作，进行复杂的<strong>减库存</strong>和<strong>生成订单</strong>操作</p>
<h4 id="超卖问题"><a href="#超卖问题" class="headerlink" title="超卖问题"></a>超卖问题</h4><p>本来只有10件商品，硬生生给减成了负数😂</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/image/20190606/m5RhIzmdXRV1.png?imageslim"
                      alt="mark"
                ></p>
<p>可以看到有16个人秒杀到了这个商品这显然是不合理的</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/image/20190606/nJmnvKvVzAHt.png?imageslim"
                      alt="mark"
                ></p>
<p>这个问题会在后面的文章中提出解决方案，这一篇主要熟悉下压测。</p>

        </div>

        
            <div class="post-copyright-info">
                <div class="article-copyright-info-container">
    <ul>
        <li>本文标题：JMeter压测</li>
        <li>本文作者：Resolmi</li>
        <li>创建时间：2019-06-06 00:00:00</li>
        <li>
            本文链接：https://imlgw.top/2019/06/06/f990e699/
        </li>
        <li>
            版权声明：本博客所有文章除特别声明外，均采用 <a class="license" target="_blank" rel="noopener" href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh">BY-NC-SA</a> 许可协议。转载请注明出处！
        </li>
    </ul>
</div>

            </div>
        

        
            <div class="article-nav">
                
                    <div class="article-prev">
                        <a class="prev"
                           rel="prev"
                           href="/2019/07/19/df38ad26/"
                        >
                            <span class="left arrow-icon flex-center">
                              <i class="fas fa-chevron-left"></i>
                            </span>
                            <span class="title flex-center">
                                <span class="post-nav-title-item">Socket网络编程</span>
                                <span class="post-nav-item">上一篇</span>
                            </span>
                        </a>
                    </div>
                
                
                    <div class="article-next">
                        <a class="next"
                           rel="next"
                           href="/2019/05/20/a28427/"
                        >
                            <span class="title flex-center">
                                <span class="post-nav-title-item">WebMvcConfigurer小结</span>
                                <span class="post-nav-item">下一篇</span>
                            </span>
                            <span class="right arrow-icon flex-center">
                              <i class="fas fa-chevron-right"></i>
                            </span>
                        </a>
                    </div>
                
            </div>
        

        
            <div class="comment-container">
                <div class="comments-container">
    <div id="comment-anchor"></div>
    <div class="comment-area-title">
        <i class="fas fa-comments">&nbsp;评论</i>
    </div>
    

        
            <section class="disqus-comments">
<div id="disqus_thread">
  <noscript>Please enable JavaScript to view the <a target="_blank" rel="noopener" href="//disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
</div>
</section>

<script>
var disqus_shortname = 'imlgw';

var disqus_url = 'https://imlgw.top/2019/06/06/f990e699/';

(function(){
  var dsq = document.createElement('script');
  dsq.type = 'text/javascript';
  dsq.async = true;
  dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
  (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>

<script id="dsq-count-scr" src="//imlgw.disqus.com/count.js" async></script>
        
    
</div>

            </div>
        
    </div>
</div>


                
            </div>

        </div>

        <div class="page-main-content-bottom">
            <footer class="footer">
    <div class="info-container">
        <div class="copyright-info info-item">
            &copy;
            
              <span>2018</span>&nbsp;-&nbsp;
            
            2021&nbsp;<i class="fas fa-heart icon-animate"></i>&nbsp;<a href="/">Resolmi</a>
        </div>
        
            <script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
            <div class="website-count info-item">
                
                    <span id="busuanzi_container_site_uv">
                        访问人数&nbsp;<span id="busuanzi_value_site_uv"></span>&ensp;
                    </span>
                
                
                    <span id="busuanzi_container_site_pv">
                        总访问量&nbsp;<span id="busuanzi_value_site_pv"></span>
                    </span>
                
            </div>
        
        
            <div class="icp-info info-item"><a target="_blank" rel="nofollow" href="https://beian.miit.gov.cn">鄂ICP备18011208号</a></div>
        
    </div>
</footer>

        </div>
    </div>

    
        <div class="post-tools">
            <div class="post-tools-container">
    <ul class="tools-list">
        <!-- TOC aside toggle -->
        
            <li class="tools-item page-aside-toggle">
                <i class="fas fa-outdent"></i>
            </li>
        

        <!-- go comment -->
        
            <li class="go-comment">
                <i class="fas fa-comment"></i>
            </li>
        
    </ul>
</div>

        </div>
    

    <div class="right-bottom-side-tools">
        <div class="side-tools-container">
    <ul class="side-tools-list">
        <li class="tools-item tool-font-adjust-plus flex-center">
            <i class="fas fa-search-plus"></i>
        </li>

        <li class="tools-item tool-font-adjust-minus flex-center">
            <i class="fas fa-search-minus"></i>
        </li>

        <li class="tools-item tool-expand-width flex-center">
            <i class="fas fa-arrows-alt-h"></i>
        </li>

        <li class="tools-item tool-dark-light-toggle flex-center">
            <i class="fas fa-moon"></i>
        </li>

        <!-- rss -->
        

        

        <li class="tools-item tool-scroll-to-bottom flex-center">
            <i class="fas fa-arrow-down"></i>
        </li>
    </ul>

    <ul class="exposed-tools-list">
        <li class="tools-item tool-toggle-show flex-center">
            <i class="fas fa-cog fa-spin"></i>
        </li>
        
            <li class="tools-item tool-scroll-to-top flex-center">
                <i class="arrow-up fas fa-arrow-up"></i>
                <span class="percent"></span>
            </li>
        
    </ul>
</div>

    </div>

    
        <aside class="page-aside">
            <div class="post-toc-wrap">
    <div class="post-toc">
        <ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#JMeter%E5%85%A5%E9%97%A8"><span class="nav-number">1.</span> <span class="nav-text">JMeter入门</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E7%AE%80%E5%8D%95%E4%B8%8A%E6%89%8B"><span class="nav-number">1.1.</span> <span class="nav-text">简单上手</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%B7%BB%E5%8A%A0%E8%87%AA%E5%AE%9A%E4%B9%89%E5%8F%82%E6%95%B0"><span class="nav-number">1.2.</span> <span class="nav-text">添加自定义参数</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E7%94%9F%E6%88%90token"><span class="nav-number">1.3.</span> <span class="nav-text">生成token</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Redis%E5%8E%8B%E6%B5%8B"><span class="nav-number">1.4.</span> <span class="nav-text">Redis压测</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%90%AD%E5%BB%BA%E5%8E%8B%E6%B5%8B%E7%8E%AF%E5%A2%83"><span class="nav-number">2.</span> <span class="nav-text">搭建压测环境</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8E%8B%E6%B5%8B"><span class="nav-number">2.1.</span> <span class="nav-text">命令行压测</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E7%8E%AF%E5%A2%83"><span class="nav-number">2.2.</span> <span class="nav-text">环境</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#SpringBoot%E6%89%93war%E5%8C%85"><span class="nav-number">2.3.</span> <span class="nav-text">SpringBoot打war包</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#SpringBoot%E6%89%93jar%E5%8C%85"><span class="nav-number">2.4.</span> <span class="nav-text">SpringBoot打jar包</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%BC%80%E5%A7%8B%E5%8E%8B%E6%B5%8B"><span class="nav-number">3.</span> <span class="nav-text">开始压测</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%8E%8B%E6%B5%8B%E5%95%86%E5%93%81%E5%88%97%E8%A1%A8%E9%A1%B5%E9%9D%A2"><span class="nav-number">3.1.</span> <span class="nav-text">压测商品列表页面</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E9%81%87%E5%88%B0%E7%9A%84%E9%97%AE%E9%A2%98"><span class="nav-number">3.2.</span> <span class="nav-text">遇到的问题</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%9C%80%E7%BB%88%E9%85%8D%E7%BD%AE"><span class="nav-number">3.3.</span> <span class="nav-text">最终配置</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#%E7%BB%93%E6%9E%9C"><span class="nav-number">3.3.1.</span> <span class="nav-text">结果</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%8E%8B%E6%B5%8BRedis%E6%9F%A5%E8%AF%A2%E7%9A%84%E6%80%A7%E8%83%BD"><span class="nav-number">3.4.</span> <span class="nav-text">压测Redis查询的性能</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#%E7%BB%93%E6%9E%9C-1"><span class="nav-number">3.4.1.</span> <span class="nav-text">结果</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E9%87%8D%E5%A4%B4%E6%88%8F%E2%80%94%E5%8E%8B%E6%B5%8Bdo-spike%E6%8E%A5%E5%8F%A3"><span class="nav-number">3.5.</span> <span class="nav-text">重头戏—压测do_spike接口</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#%E8%B6%85%E5%8D%96%E9%97%AE%E9%A2%98"><span class="nav-number">3.5.1.</span> <span class="nav-text">超卖问题</span></a></li></ol></li></ol></li></ol>
    </div>
</div>
        </aside>
    

    <div class="image-viewer-container">
    <img src="">
</div>


    
        <div class="search-pop-overlay">
    <div class="popup search-popup">
        <div class="search-header">
          <span class="search-input-field-pre">
            <i class="fas fa-keyboard"></i>
          </span>
            <div class="search-input-container">
                <input autocomplete="off"
                       autocorrect="off"
                       autocapitalize="off"
                       placeholder="搜索..."
                       spellcheck="false"
                       type="search"
                       class="search-input"
                >
            </div>
            <span class="popup-btn-close">
                <i class="fas fa-times"></i>
            </span>
        </div>
        <div id="search-result">
            <div id="no-result">
                <i class="fas fa-spinner fa-pulse fa-5x fa-fw"></i>
            </div>
        </div>
    </div>
</div>

    

</main>



<script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/utils.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/main.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/header-shrink.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/back2top.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/dark-light-toggle.js"></script>


    <script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/local-search.js"></script>



    <script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/code-copy.js"></script>



    <script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/lazyload.js"></script>


<div class="post-scripts pjax">
    
        <script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/left-side-toggle.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/libs/anime.min.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/toc.js"></script>
    
</div>


    <script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/libs/pjax.min.js"></script>
<script>
    window.addEventListener('DOMContentLoaded', () => {
        window.pjax = new Pjax({
            selectors: [
                'head title',
                '.page-container',
                '.pjax'
            ],
            history: true,
            debug: false,
            cacheBust: false,
            timeout: 0,
            analytics: false,
            currentUrlFullReload: false,
            scrollRestoration: false,
            // scrollTo: true,
        });

        document.addEventListener('pjax:send', () => {
            KEEP.utils.pjaxProgressBarStart();
        });

        document.addEventListener('pjax:complete', () => {
            KEEP.utils.pjaxProgressBarEnd();
            window.pjax.executeScripts(document.querySelectorAll('script[data-pjax], .pjax script'));
            KEEP.refresh();
        });
    });
</script>



<script src="https://cdn.jsdelivr.net/npm/live2d-widget@3.x/lib/L2Dwidget.min.js"></script><script>L2Dwidget.init({"pluginRootPath":"live2dw/","pluginJsPath":"lib/","pluginModelPath":"assets/","tagMode":false,"debug":false,"model":{"jsonPath":"https://cdn.jsdelivr.net/npm/live2d-widget-model-hijiki@1.0.5/assets/hijiki.model.json"},"display":{"superSample":2,"width":160,"height":320,"position":"right","hOffset":0,"vOffset":-70},"mobile":{"show":false,"scale":0.2},"log":false});</script></body>
</html>
